package com.jjy.admin.service.job.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jjy.common.core.LambdaQueryWrapperX;
import com.jjy.common.domain.PageResult;
import com.jjy.admin.domain.JobEntity;
import com.jjy.admin.domain.JobSpiderDTO;
import com.jjy.admin.mapper.JobMapper;
import com.jjy.admin.service.job.JobService;
import com.jjy.admin.utils.StrFormatUtil;
import com.jjy.admin.utils.WebDriverUtil;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

@Service
public class JobServiceImpl implements JobService {
    private static final String url;
    private static String changeUrl;
    private static final Logger log = LoggerFactory.getLogger(  JobServiceImpl.class);
    static {
        url ="https://we.51job.com/api/job/search-pc?api_key=51job&timestamp=1711957276&keyword={keyword}&searchType=2&function=&industry=&jobArea=000000&jobArea2=&landmark=&metro=&salary=&workYear=&degree=03%2C04%2C05&companyType=&companySize=&jobType=&issueDate=1&sortType=0&pageNum={pageNum}&requestId=&pageSize={pageSize}&source=1&accountId=&pageCode=sou%7Csou%7Csoulb";
    }

    @Resource
    private JobMapper jobMapper;


    @Override
    public PageResult<JobEntity> page(JobEntity jobEntity) {

        return jobMapper.selectPage(jobEntity);
    }

    @Override
    public  List<JobEntity> exportList(JobEntity jobEntity) {
         return jobMapper.selectList(new LambdaQueryWrapperX<JobEntity>()
                .eqIfPresent(JobEntity::getProvince,jobEntity.getProvince())
                .eqIfPresent(JobEntity::getCity,jobEntity.getCity())
                .eqIfPresent(JobEntity::getDegree,jobEntity.getDegree())
                .eqIfPresent(JobEntity::getIndustryType1,jobEntity.getIndustryType1())
                .likeIfPresent(JobEntity::getExperience,jobEntity.getExperience())
                .likeIfPresent(JobEntity::getJobName,jobEntity.getJobName())
        );

    }


    @Override
    public int doSpider(JobSpiderDTO jobSpider) {
        WebDriver webDriver = WebDriverUtil.getWebDriver();
//记录插入总数
        int count=0;
        int pageNum = jobSpider.getPageNum();
//        ArrayList<JobEntity> jobEntities = new ArrayList<>();
        for (int i2 = 1; i2 <=pageNum ; i2++) {
            JsonNode jsonNode = null;
            try {
                jsonNode = getJson(jobSpider.getKeyWord(), i2, jobSpider.getPageSize(), webDriver);

            JsonNode resultBody = jsonNode.get("resultbody");
            JsonNode job = resultBody.get("job");
            JsonNode items = job.get("items");
            for (int i = 0; i < items.size(); i++) {
                JobEntity jobEntity = new JobEntity();
                String jobName = items.get(i).get("jobName").asText();
                JsonNode jobTags = items.get(i).get("jobTags");
                String tag = "";
                for (int i3 = 2; i3 < jobTags.size(); i3++) {
                    String text = jobTags.get(i3).asText();
                    tag=tag.concat(text).concat(",");
                }
//jobTags中存着公司福利，需要单独处理
//                定义一个福利的关键词
                String[] giftWord={  "福","补","奖","津","五","法","休","薪","体","团","险"};
                for (int j = 0; j < jobTags.size(); j++) {
                    for (int k = 0; k < giftWord.length; k++) {
                        if ( jobTags.get(j).asText().contains(giftWord[k])){
                            jobMapper.insertGiftWord(jobTags.get(j).asText());
                        };
                    }
                }

                String jobAreaString = items.get(i).get("jobAreaString").asText();
                String provideSalaryString = items.get(i).get("provideSalaryString").asText();
                String industryType1 = items.get(i).get("industryType1").asText();
                String industryType2 = items.get(i).get("industryType2").asText();
                String industryType1Str = items.get(i).get("industryType1Str").asText();
                String industryType2Str = items.get(i).get("industryType2Str").asText();
                String companyName = items.get(i).get("companyName").asText();
                String fullCompanyName = items.get(i).get("fullCompanyName").asText();
                String companyType = items.get(i).get("companyTypeString").asText();
                String companySizeString = items.get(i).get("companySizeString").asText();
                String jobHref = items.get(i).get("jobHref").asText();
                String jobDescribe = items.get(i).get("jobDescribe").asText();
                String jobSalaryMax = items.get(i).get("jobSalaryMax").asText();
                String jobSalaryMin = items.get(i).get("jobSalaryMin").asText();
                String experience = jobTags.get(0).asText();
                String degree = jobTags.get(1).asText();
                JsonNode jobAreaLevelDetail = items.get(i).get("jobAreaLevelDetail");
                String province = jobAreaLevelDetail.get("provinceString").asText();
                String city = jobAreaLevelDetail.get("cityString").asText();

//              数据清理
                String needCleanData[]={jobName, tag, jobAreaString,
                        provideSalaryString,jobSalaryMax, jobSalaryMin, experience, degree, city};
                boolean isCleanData = cleanData(needCleanData);
//              经过数据检测的写入数据库
                if (isCleanData){
                jobEntity.setJobName(jobName);
                jobEntity.setJobTags(tag);
                jobEntity.setJobArea(jobAreaString);
                jobEntity.setProvideSalary(provideSalaryString);
                jobEntity.setIndustryType1Id(industryType1);
                jobEntity.setIndustryType2Id(industryType2);
                jobEntity.setIndustryType1(industryType1Str);
                jobEntity.setIndustryType2(industryType2Str);
                jobEntity.setCompanyName(companyName);
                jobEntity.setFullCompanyName(fullCompanyName);
                jobEntity.setCompanyType(companyType);
                jobEntity.setCompanySize(companySizeString);
                jobEntity.setJobHref(jobHref);
                jobEntity.setJobDescribe(jobDescribe);
                jobEntity.setJobSalaryMax(jobSalaryMax);
                jobEntity.setJobSalaryMin(jobSalaryMin);
                jobEntity.setExperience(experience);
                jobEntity.setDegree(degree);
                jobEntity.setProvince(province);
                jobEntity.setCity(city);
                int insert = jobMapper.insert(jobEntity);
                count = count + insert;
                }
            }
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
            WebDriverUtil.closeWebDriver();
//        jobMapper.insertBatch(jobEntities);
        if (count!=0){
            return count;
        }else {
            return 0;
        }
        }

//定义非法字符集
    private static final String ILLEGAL_CHARACTERS = "!@#$%^&*()_+<>:";

    private boolean cleanData(String[] needCleanData) {
//        1.进行空格处理
        for (int i = 0; i < needCleanData.length; i++) {
            needCleanData[i]=needCleanData[i].replaceAll(" ","");
        }
//        2.进行null值处理
        for (int i = 0; i < needCleanData.length; i++) {
            if (null==needCleanData[i]||needCleanData[i].equals("")){
                return false;
            }
        }
//        3.进行非法字符处理
        for (int i = 0; i < needCleanData.length; i++) {
            for (int i1 = 0; i1 < ILLEGAL_CHARACTERS.length(); i1++) {
                if (needCleanData[i].contains(ILLEGAL_CHARACTERS.substring(i1,i1+1))){
                    return false;
                }
            }
        }
        return true;
    }

// 数据清洗



    private static JsonNode getJson(String keyWord, int pageNum, int pageSize, WebDriver driver) {

        changeUrl=url;
        changeUrl=changeUrl.replace("{keyword}",keyWord);
        changeUrl=changeUrl.replace("{pageNum}",String.valueOf(pageNum));
        changeUrl=changeUrl.replace("{pageSize}",String.valueOf(pageSize));

        // 2.打开网址
        driver.get(changeUrl);
//
        log.info("爬取url = " + changeUrl);
        log.info("页面加载中...");
            JsonNode jsonNode = null;
        try {
            String pageSource = driver.getPageSource();
            while (pageSource.contains(  "滑动验证页面")||pageSource.contains("点击框体重试")) {
                if (pageSource.contains("滑动验证页面")){
                    pageSource= checkSlidePage(driver, pageSource);
                }else if (pageSource.contains("点击框体重试")){
                    pageSource= checkErrLoad(driver, pageSource);
                }
            }
                String json = StrFormatUtil.getStr(pageSource);
                ObjectMapper mapper = new ObjectMapper();
                jsonNode = mapper.readTree(json);
        } catch (JsonProcessingException | InterruptedException e) {
            e.printStackTrace();
        }
        return jsonNode;
    }

    private static String  checkSlidePage(WebDriver driver, String pageSource) throws InterruptedException {

        WebElement element = driver.findElement(By.cssSelector(".nc_iconfont.btn_slide"));
//           模拟点击
        element.click();
//防止处理未完成，停一下给电脑反应
//        Thread.sleep(3000);
//            移动滑块
        Actions actions = new Actions(driver);
        actions.clickAndHold(element).moveByOffset(300, 0).release().build().perform();
        //防止页面未完成加载，停一下给电脑反应
//        Thread.sleep(5000);
        String driverPageSource = driver.getPageSource();
        try {
//            页面加载了错误滑块但是反应不过来，尝试点击（如果有）
            WebElement element1 = driver.findElement(By.cssSelector(".nc-container .nc_wrapper .errloading"));
            element1.click();
        } finally {

        return driverPageSource;
        }
    }

    private static String checkErrLoad(WebDriver driver, String pageSource) {
        if (pageSource.contains("点击框体重试")){
            WebElement element = driver.findElement(By.cssSelector(".nc-container .nc_wrapper .errloading"));
//           模拟点击
            element.click();
            pageSource = driver.getPageSource();
        }
            return pageSource;
    }


}



